<template>
  <div
    ref="scrollContainer"
    class="scroll-container"
    @touchstart="handlerTouchStart"
    @touchmove="handlerTouchMove"
  >
    <div ref="slotDom" class="table_slot" :style="scrollStyle"><slot></slot></div>
    <div class="loading" v-if="downPullLock">
      <hxm-loading>加载中...</hxm-loading>
    </div>
    <div class="up_pull_container" v-else :style="bottom">
      <div class="up_pull">{{ upWord }}</div>
    </div>
  </div>
</template>

<script>
// IOS客户端新版本禁用回弹失效，取消自己写的回弹动画
export default {
  data() {
    return {
      //整体dom
      bodyDom: null,
      // 插槽的dom
      slotDom: null,
      // table的偏移，代替滚动
      scrollStyle: '',
      // 占位文案，↑上拉加载更多
      upWord: '',
      downWord: '下拉加载后一天内容',
      // 记录移动的距离
      distance: '',
      downPullEnable: false,
      downHTML: '下拉加载后一天内容',
      downTriggerHTML: '↑松开可以刷新',
      upHTML: '上拉加载前一天内容',
      upTriggerHTML: '松开加载数据',
      loadHTML:
        '<img class="loading" src="//i.thsi.cn/m/static/loading.png" style="height:0.4rem">加载中',
      loadScrollPX: 0.76,
      scrollJudgeSize: 150,
      startY: 0,
      // 用来标志回弹的距离和方向
      distY: 0,
      downPullLock: false,
    };
  },
  props: {
    upPullEnable: {
      type: Boolean,
      default: true,
    },
    downPullEvent: {
      type: Function,
    },
    upPullEvent: {
      type: Function,
    },
    bottom: {
      type: String,
      default: '',
    },
  },
  watch: {},
  methods: {
    // 获取手指触屏时的屏幕Y轴位置
    handlerTouchStart(e) {
      this.startY = e.touches[0].pageY;
      this.distY = 0;
    },
    // 获取手指移动的距离
    handlerTouchMove(e) {
      this.touchMoveEvent(e);
    },
    touchMoveEvent(e) {
      // 操作位置允许一定的偏差,ios存在1px误差，多保留保证交互效果
      const errheight = 5;
      // 加入最短时间，这里因为需要回调控制，不用节流
      const loadingMin = 300;
      if (!this.bodyDom) {
        return;
      }
      this.distY = e.touches[0].pageY - this.startY;
      // 处理部分机型问题，目前没想到更好方案
      const scrollTop = this.getScrollTop();
      // 到底部或者顶部时，添加transform动画
      if (
        this.upPullEnable &&
        document.documentElement.clientHeight + scrollTop >=
          this.bodyDom.scrollHeight - errheight &&
        this.distY < 0
      ) {
        if (!this.downPullLock) {
          this.upWord = '';
          this.downPullLock = true;
          setTimeout(() => {
            this.upPullEvent('', this.end());
          }, loadingMin);
        }
      } else {
        // 常规滚动不做处理
      }
    },

    getScrollTop() {
      return this.bodyDom.scrollTop || document.body.scrollTop || 0;
    },
    end() {
      this.downPullLock = false;
      if (this.upPullEnable) {
        this.upWord = '';
      }
    },
  },
  mounted() {
    this.bodyDom = this.$refs.scrollContainer;
    this.slotDom = this.$refs.slotDom;
  },
};
</script>
<style lang="less" scoped>
.loading {
  height: 0.66rem;
  display: flex;
  justify-content: center;
  align-items: center;
}
.scroll-container {
  overflow: scroll;
  height: 100vh;
  -webkit-overflow-scrolling: touch;
  background-color: #f5f5f5;
  &::-webkit-scrollbar {
    display: none;
  }
}
.down_pull {
  top: 0;
  position: relative;
  left: 0;
  z-index: 1;
  text-align: center;
  width: 100%;
  height: 0;
  line-height: 0.66rem;
  font-size: 0.24rem;
  color: #ababb8;
}
.up_pull {
  bottom: 0;
  position: absolute;
  left: 0;
  z-index: 1;
  text-align: center;
  width: 100%;
  height: 0.66rem;
  font-size: 0.24rem;
  color: #ababb8;
  line-height: 0.66rem;
}
.up_pull_container {
  position: relative;
  width: 100%;
  height: 0;
}
.table_slot {
  position: relative;
  z-index: 2;
}
</style>
